package com.scujj.controller.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.scujj.controller.OfferController;
import com.scujj.enums.OfferStatus;
import com.scujj.pojo.Offer;
import com.scujj.pojo.OrderOffer;
import com.scujj.pojo.Result;
import com.scujj.pojo.User;
import com.scujj.service.OfferOrderService;
import com.scujj.service.OfferService;
import com.scujj.service.UserService;
import com.scujj.util.FileUtil;
import com.scujj.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;


@RestController
@RequestMapping("/offer")
@RefreshScope
public class OfferControllerImpl implements OfferController {

    @Autowired
    UserService userService;

    @Autowired
    OfferService offerService;

    @Autowired
    OfferOrderService orderService;

    @Value("${staticFilePath}")
    String rootFilePath;

    @Value("${imgPath.offerMedia}")
    String offerMediaPath;

    @Value("${staticFilePath}" + "${imgPath.offerMedia}")
    String offerMediaFullPath;



    @Override
    @PostMapping("/create")
    public Result createOffer(
                              @RequestParam(required = false,name = "context") String context,
                              @RequestParam(required = false,name = "title") String title,
                              @RequestParam(required = false,name = "bounty") String bountyString,
                              @RequestHeader HashMap<String,String> header,
                              @RequestParam(value = "images",required = false) MultipartFile[] images) {
        Result result=userService.getUserByToken(header);
        if(result.getCode()==-1){
            return result;
        }
        User user = ResultUtil.singleTrans(result.getData(),User.class);
//        String context=req.get("context");
//        String bountyString= req.get("bounty");
//        String title=req.get("title");
        if(title==null) {
            return Result.error("标题不能为空");
        }
        if(context==null){
            return Result.error("内容不能为空");
        }
        if(bountyString==null){
            return Result.error("补贴不能为空");
        }
        long bounty= Long.parseLong(bountyString);
        if(bounty<=0){
            return Result.error("补贴必须大于0");
        }
        String imgPath=FileUtil.uploadFiles(rootFilePath,offerMediaPath,images);
        Offer offer=new Offer();
        offer.setUid(user.getId());
        offer.setContext(context);
        offer.setPrice(bounty);
        offer.setStatus(OfferStatus.UNPAID.state);
        offer.setTitle(title);
        offer.setImgSrc(imgPath);
        offer.setStartTime(new Date());
        offerService.save(offer);
        return Result.success("求助发布成功, 请付款",offer);
    }

    @Override
    @GetMapping ("/check_status")
    public Result checkOfferPaid(@RequestParam String offerId,@RequestHeader HashMap<String, String> header) {
        Result result=userService.getUserByToken(header);
        if(result.getCode()==-1){
            return result;
        }
        User user = ResultUtil.singleTrans(result.getData(),User.class);
        Offer offer=offerService.getById(offerId);
        if(!Objects.equals(offer.getUid(), user.getId())){
            return Result.error("你没有权限访问此接口");
        }
        return Result.success(offer.getStatus());
    }

    @Override
    @GetMapping("/offer_list/last")
    public Result showUnacceptedOffersLast(@RequestParam(required = false,defaultValue = "1") int page,@RequestParam(required = false,defaultValue = "10") int limit) {
        if(page<1){
            return Result.error("页数不能小于1");
        }
        if(limit<1){
            return Result.error("每页数量不能小于1");
        }
        QueryWrapper<Offer> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("startTime");
        wrapper.eq("status",OfferStatus.PAID.state);


        Page<Offer> pageObj = new Page<>(page,limit);
        offerService.page(pageObj,wrapper);
        return Result.success(offerResultSet(pageObj.getRecords()));
    }


    @Override
    @GetMapping("/offer_list/costly")
    public Result showUnacceptedOffersCostly(@RequestParam(required = false,defaultValue = "1") int page,@RequestParam(required = false,defaultValue = "10") int limit) {
        if(page<1){
            return Result.error("页数不能小于1");
        }
        if(limit<1){
            return Result.error("每页数量不能小于1");
        }
        QueryWrapper<Offer> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("price");
        wrapper.eq("status",OfferStatus.PAID.state);


        Page<Offer> pageObj = new Page<>(page,limit);
        offerService.page(pageObj,wrapper);
        return Result.success(offerResultSet(pageObj.getRecords()));
    }

    public List<Offer> offerResultSet(List<Offer> offers){
        List<Long> ids= new LinkedList<>();
        offers.forEach(offer -> {
            ids.add(offer.getUid());
        });
        if (ids.isEmpty()) {
            return offers;
        }
        HashMap<Long, User> userMap = getUserMap(ids);
        offers.forEach(offer -> {
            offer.setUser(userMap.get(offer.getUid()));
        });
        return offers;
    }

    public HashMap<Long, User> getUserMap(List<Long> ids) {
        Result r = userService.getUserByIdList(ids);
        List<User> users = ResultUtil.listTrans(r.getData(), User.class);
        HashMap<Long, User> userMap = new HashMap<>();
        users.forEach(u -> {
            userMap.put(u.getId(), u.setPassword(null).setPhoneNumber(null).setMoney(0L));
        });
        return userMap;
    }

    @Override
    @GetMapping ("/accept/{id}")
    @Transactional
    public Result acceptOffer(@PathVariable String id,@RequestHeader HashMap<String, String> header){
        Long oid=Long.parseLong(id);
        Offer offer=offerService.getById(oid);
        if(offer==null){
            return Result.error("没有此订单");
        }
        if(offer.getStatus()!=OfferStatus.PAID.state){
            return Result.error("此订单不可接受");
        }
        Result result=userService.getUserByToken(header);
        if(result.getCode()==-1){
            return result;
        }
        User user = ResultUtil.singleTrans(result.getData(),User.class);
        if(Objects.equals(offer.getUid(), user.getId())){
            return Result.error("你无法接受自己的求助");
        }
        long userMoney= user.getMoney();
        if(offer.getPrice()*2>userMoney){
            return Result.error("账户金额必须为订单金额的两倍以上");
        }

        // 扣双倍钱, 订单完成后返还, 未完成将作为赔偿金
        HashMap<String, Long> useMoneyParams=new HashMap<>();
        useMoneyParams.put("id",user.getId());
        useMoneyParams.put("money",offer.getPrice()*2);
        userService.useMoney(useMoneyParams);

        offer.setStatus(OfferStatus.ACCEPTED.state);
        offerService.updateById(offer);

        QueryWrapper<OrderOffer> orderWrapper = new QueryWrapper<>();
        orderWrapper.eq("oid",offer.getId());

        OrderOffer order = orderService.getOne(orderWrapper);
        order.setStatus(OfferStatus.ACCEPTED.state);
        order.setUid(user.getId());
        orderService.updateById(order);
        return Result.success("抢订单成功");
    }

    @Override
    @GetMapping("/del")
    @Transactional
    public Result delOffer(@RequestParam Long id,@RequestHeader HashMap<String, String> header) {
        Result result=userService.getUserByToken(header);
        if(result.getCode()==-1){
            return result;
        }
        User user = ResultUtil.singleTrans(result.getData(),User.class);
        Offer offer=offerService.getById(id);
        if(offer==null){
            return Result.error("没有此订单");
        }
        if(!Objects.equals(offer.getUid(), user.getId())){
            return Result.error("你没有权限删除此订单");
        }
        if(offer.getStatus()==OfferStatus.ACCEPTED.state){
            return Result.error("已被接单, 无法删除");
        }
        offerService.removeById(id);
        HashMap<String,Long> addMoneyParam=new HashMap<>();
        addMoneyParam.put("id",user.getId());
        addMoneyParam.put("money", offer.getPrice());
        userService.addMoney(addMoneyParam);
        return Result.success("删除成功");
    }

    @Override
    @GetMapping("/mine")
    public Result showOfferOfUser(@RequestParam(required = false,defaultValue = "1") int page,@RequestParam(required = false,defaultValue = "5") int limit,@RequestHeader HashMap<String, String> header) {
        if(page<1){
            return Result.error("页数不能小于1");
        }
        if(limit<1){
            return Result.error("每页数量不能小于1");
        }
        Result result=userService.getUserByToken(header);
        if(result.getCode()==-1){
            return result;
        }
        User user = ResultUtil.singleTrans(result.getData(),User.class);
        QueryWrapper<Offer> wrapper = new QueryWrapper<>();
        wrapper.eq("uid",user.getId());
        wrapper.orderByDesc("startTime");
        Page<Offer> pageObj = new Page<>(page,limit);
        pageObj = offerService.page(pageObj,wrapper);
        return Result.success(pageObj.getRecords());
    }

    @Override
    @GetMapping("/byId")
    public Result getOfferById(@RequestParam(required = false) String id,@RequestParam(required = false, defaultValue = "1") int page,@RequestParam(required = false, defaultValue = "5") int limit) {
        if(page<1){
            return Result.error("页数不能小于1");
        }
        if(limit<1){
            return Result.error("每页数量不能小于1");
        }

        if(id==null){
            return Result.error("用户id不能为空");
        }
        QueryWrapper<Offer> wrapper = new QueryWrapper<>();
        wrapper.eq("uid",Long.valueOf(id));
        wrapper.eq("status",OfferStatus.PAID.state);
        Page<Offer> pageObj = new Page<>(page,limit);
        pageObj = offerService.page(pageObj,wrapper);
        return Result.success(offerResultSet(pageObj.getRecords()));
    }
}
